/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package servlets;

import com.sun.tools.xjc.reader.xmlschema.bindinfo.BIConversion.User;
import java.sql.SQLException;
import dbhandler.DBConnector;
import dbhandler.SecureAlgorithm;
import java.sql.CallableStatement;
import java.sql.SQLException;
import java.util.*;
import java.io.*;
import java.net.*;
import java.sql.ResultSet;
import java.util.regex.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang.WordUtils;
import com.mysql.jdbc.PreparedStatement;
import java.io.IOException;
import java.util.ArrayList;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServlet;
import java.util.Arrays;
import dbhandler.DBConnector;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.sql.CallableStatement;
import security.Validation;
import javax.servlet.*;
import javax.servlet.http.*;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.lang.String;
import java.security.SecureRandom;

/**
 *
 * @author Jaice
 */
public class LoginServlet {

    private String userName;
    private String password;
    private String strError;
    private Hashtable errors;
    private Integer count;
    private String sessionid;
    private int accounttype;
    private String firstName;
    private String lastName;
    private String middleInitial;
    private String email;
    private String FullName;

    public String getFullName() {
        return FullName;
    }

    public void setFullName(String FullName) {
        this.FullName = FullName;
    }

    public String getDatecreated() {
        return datecreated;
    }

    public void setDatecreated(String datecreated) {
        this.datecreated = datecreated;
    }

    public String getLastlogin() {
        return lastlogin;
    }

    public void setLastlogin(String lastlogin) {
        this.lastlogin = lastlogin;
    }
    private String lastlogin;
    private String datecreated;

    public boolean login() throws SQLException, ClassNotFoundException, java.lang.NullPointerException, IOException {
        boolean check = false;

        System.out.println("username: " + userName);
        System.out.println("password: " + password);

        try {

            System.out.println("login");

            String digest = null;
            String salt = null;
            boolean authenticated = false;
            boolean userExist = true;
            DBConnector dbConnector = null;
            dbConnector = new DBConnector("localhost", 3306, "selector", "53l3ct0r", "bookaholic");

            if (userName.equals("null") || password.equals("null")) { // TIME RESISTANT ATTACK 
                // Computation time is equal to the time needed by alegitimate user 
                userExist = false;
                userName = "";
                password = "";
                strError = "Invalid username or password";
                errors.put("StrError", "Invalid username or password");
            }

            dbConnector.connectToDB();
            CallableStatement callable = null;
            ResultSet result = null;
            String authCall = "{ call login2(?) }";
            callable = dbConnector.getConnection().prepareCall(authCall);
            callable.setString(1, userName);
            result = callable.executeQuery();
            if (result.next()) {
                digest = result.getString("hashpassword");
                salt =
                        result.getString("salt");


                byte[] bDigest = dbConnector.base64ToByte(digest);
                byte[] bSalt = dbConnector.base64ToByte(salt);
            } else { // TIME RESISTANT ATTACK (Even if the user does not existthe 
                // Computation time is equal to the time needed for a legitimate user 
                digest = "000000000000000000000000000=";
                salt = "00000000000=";
                userExist = false;
                strError = "Invalid username or password";
                errors.put("StrError", "Invalid username or password");
            }
            byte[] bDigest =
                    dbConnector.base64ToByte(digest);
            byte[] bSalt =
                    dbConnector.base64ToByte(salt);
            byte[] proposedDigest =
                    dbConnector.getHash(password, bSalt);

            if (Arrays.equals(proposedDigest, bDigest)) {

                ///////////////////////
                result=null;
                String authCall1 = "{ call get_date_name_all(?) }";
                callable = dbConnector.getConnection().prepareCall(authCall1);
                callable.setString(1, userName);
                result = callable.executeQuery();

                while (result.next()) {
                    lastlogin = result.getString("lastlogin");
                    datecreated = result.getString("datecreated");
                    FullName=result.getString("lname")+", "+result.getString("fname")+" "+ result.getString("mi")+".";
                }
                result=null;
                String authCall2 = "{ call change_lastlogin(?) }";
                callable = dbConnector.getConnection().prepareCall(authCall2);
                callable.setString(1, userName);
                result = callable.executeQuery();
                ///////////////////////
                SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
                byte[] bsessionid = new byte[32];
                sr.nextBytes(bsessionid);
                String ssessionid = dbConnector.byteToBase64(bsessionid);
                sessionid = ssessionid;
                accounttype = dbConnector.getaccounttype(userName, password);
                firstName = dbConnector.getfname(userName, password);
                check = true;
            } else {
                userName = "";
                password = "";
                strError = "Invalid username or password";
                errors.put("StrError", "Invalid username or password");
            }

            System.out.println(Arrays.equals(proposedDigest, bDigest));




        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(LoginServlet.class.getName()).log(Level.SEVERE,
                    null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(LoginServlet.class.getName()).log(Level.SEVERE,
                    null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(LoginServlet.class.getName()).log(Level.SEVERE,
                    null, ex);
        } finally {

            return check;
        }



    }

    public int getAccounttype() {
        return accounttype;
    }

    public void setAccounttype(int accounttype) {
        this.accounttype = accounttype;
    }

    public String getSessionid() {
        return sessionid;
    }

    public void setSessionid(String sessionid) {
        this.sessionid = sessionid;
    }

    public void setCount(Integer count) {
        this.count = count;
    }

    public Integer getCount() {
        return count;
    }

    public String getErrorMsg(String s) {
        String errorMsg = (String) errors.get(s.trim());
        return (errorMsg == null) ? "" : errorMsg;
    }

    public String getStrError() {
        return strError;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password =
                password;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName =
                userName;

    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getMiddleInitial() {
        return middleInitial;
    }

    public void setMiddleInitial(String middleInitial) {
        this.middleInitial = middleInitial;
    }

    public LoginServlet() {

        userName = "";
        password = "";
        strError = null;
        errors = new Hashtable();
        System.out.println(count + " :count");
        count = 0;


    }
}
